The CmdletBinding and the Parameter attribute turn a simple function into an advanced function, thereby adding features that are common in cmdlets.
Advanced functions were originally called script cmdlets because they allow you to script commands that behave essentially like compiled cmdlets. Their leaner counterparts are called simple, standard, or normal functions.
Cmdlets share a common set of features to make our work in an interactive environment consistent. For instance, cmdlets support common parameters such as -ErrorAction or -WhatIf, they prompt for confirmation if you are about to run a command with high impact, or they force you to pass mandatory parameters. These are all features that simple functions lack but that are available in advanced functions.
Two ways exist to create an advanced function: you can either add the CmdletBinding attribute or add the Parameter attribute. It is also possible to work with both attributes in the same function.
The purpose of the Parameter attribute is to specify certain features of the function’s parameters, such as making a parameter mandatory or defining its position in the command as is common in cmdlets.
You can use the CmdletBinding attribute to add basic cmdlet features, such as common parameters, to functions or to make certain methods available that allow you to change the behavior of the function. Let’s look at some examples.
The simplest advanced function I can think of looks like this:
Function Go-Advanced { [CmdletBinding()]Param() }
Note that the Param keyword is required here even if you don’t define parameters in your function.
The easiest way to find out if a function is recognized as advanced is to check whether it supports common parameters. If you run the above function in PowerShell ISE and then type its name on the command prompt with a hyphen, the PowerShell ISE auto completion feature presents you with a list of common parameters.
We already know that a workflow is actually a set of independent activies running one after each other. It is possible to make a workflow resiliant either after one specefic activty, or directly once the workflow is started.
Aside from demonstrating how an advanced function can be built, this function has no other purpose. Let’s look at an example where you can actually use one of those common parameters that PowerShell automatically added to our function. In the example below, we use the Write-Verbose cmdlet, which allows you to display a message if a function is called with the common parameter -Verbose.
Function Go-Verbose { [CmdletBinding()]Param() Write-Verbose "Print Verbose" Write-Host "Print Host" }
This is all very simple, and you could easily add this kind of functionality to your function by yourself. This applies to many features of advanced functions. However, the point is that it saves you time if you use the built-in features of advanced functions.
The next function demonstrates the usage of the ShouldContinue method, which can be helpful if you want to work with confirmation requests. You can access this method through the automatic variable $PSCmdlet, which is only available in advanced functions. In addition, the CmdletBinding attribute has to set the SupportsShouldProcess parameter to $True.
Function Remove-ByForce { [cmdletbinding(SupportsShouldProcess)] Param([string]$File) If ($PSCmdlet.ShouldContinue("Are you sure that you know what you are doing?","Delete with -Force parameter!")) { Remove-Item $File -Force } Else { "Mission aborted!" } } Remove-ByForce test -Confirm
The ShouldContinue method produces a confirmation request. If the user clicks No, the message in the Else block will be displayed.
If you want the request to show up even without the use of the -Confirm parameter, you have to first set the $ConfirmPreference variable to “Low,” which makes PowerShell prompt for confirmation when running cmdlets with a low, medium, or high risk.
Function Remove-ByForce { [CmdletBinding(SupportsShouldProcess)] Param([String]$File) $ConfirmPreference = "Low" If ($PSCmdlet.ShouldContinue("Are you sure that you know what you are doing?","Delete with -Force parameter!")) { Remove-Item $File -Force } Else { "Mission aborted!" } } Remove-ByForce test
As mentioned above, instead of using the CmdletBinding attribute, you can create an advanced function with the Parameter attribute. Don’t confuse the Parameter attribute with the Param keyword. The latter is used to define parameters in simple and advanced functions, whereas the Parameter attribute is for limiting the values of parameters in advanced functions.
Function Go-Advanced { Param( [Parameter()] $myParameter ) }
In the example, the parameter $myParameter is defined as we would do it in a standard function. We can then use this parameter to pass data to the function. The Parameter attribute doesn’t do anything else here other than telling the PowerShell engine that our function is supposed to have advanced features. In the next example, the Parameter attribute ensures that our parameter is mandatory.
Function Make-Mandatory { Param( [Parameter(Mandatory)] $myParameter ) }
If you call a function without passing a value for a mandatory parameter, PowerShell will prompt you to supply the value.
The function in the next example allows you to copy items recursively from a source to either one or two destinations depending on the parameters you specify. For each case, we create a parameter set—that is, a collection of parameters that can be used together in the command. The $Source parameter does not belong to a particular parameter set, which means it can be used with the parameters of both sets. We also set the Position argument for the $Source parameter, which means that you can omit the parameter name if the first argument you pass is the source path.
Function Copy-OneTwo { Param( [Parameter(Mandatory=$True, Position=0)] [String]$Source, [Parameter(Mandatory=$True, ParameterSetName="OneDestination")] [String]$Destination, [Parameter(Mandatory=$True, ParameterSetName="TwoDestinations")] [String]$Destination1, [Parameter(Mandatory=$True, ParameterSetName="TwoDestinations")] [String]$Destination2 ) switch ($PsCmdlet.ParameterSetName){ "OneDestination" { Copy-Item -Recurse $Source $Destination } "TwoDestinations" { Copy-Item -Recurse $Source $Destination1; Copy-Item $Source $Destination2 } } }
To view the syntax of the function with its parameters set, you can use the Get-Help cmdlet.
Source :: Michael Pietroforte(https://4sysops.com/archives/powershell-advanced-functions-the-cmdletbinding-and-parameter-attribute)